# calcGUI.py                                   David MacQuigg  ece373  11/30/07
'''Module to provide a Calculator GUI, including an interface for button clicks
and keyboard entries.  Also displays the stack of operands maintained by the
Calculator module.'''

from graphics import *  # primitives for the GUI (from John Zelle's excellent
                        # package http://mcsp.wartburg.edu/zelle/python/).

class CalcGUI(GraphWin):
    '''A Calculator GUI with buttons and display registers.'''

    def __init__(self, width, height):
        '''Set up a calculator GUI with standard buttons and a stack display,
        given width (number of chars) and height (number of registers) of the
        stack.  Buttons include
        ('+', 'N', '-', '*', '/', 'I', 'M', digits 0-9, and '.')
        '''

    def displayLine(self, regnum, strValue):
        '''Refresh the display of register regnum, replacing its current
        contents with strValue.  No checking is done other than to throw an
        IndexError if regnum is out of range, or a TypeError if strValue is not
        a string.  Register 0 is at the bottom.'''

    def getNext(self):
        '''Returns an item code and an item entered by a button click or by
        keyboard input to the bottom display register.  If a button click, the
        item code is "B", and the item is the label on the button.  If a
        keyboard entry, the item code is whatever string appears ahead of the
        first colon in the bottom register, and the item is the Python object
        represented by the string to the right of the first colon.  See method
        _makeObject for examples.'''

    def _makeObject(self, strEntry):
        '''Parses a user-input string like "X: {1: 10, 3: 30}", where X is a
        code indicating the type of Calculator object, and the string to the
        right of the colon is any valid Python object.

        Returns two items - the object code and the Python object, constructed
        using Python's eval function, This string is checked to eliminate
        potentially malicious input to eval, but the final conversion to a
        valid operand must be done by the Calculator.

        >>> cgui._makeObject(poly1)
        'P', {1: 10, 3: 30}

        >>> cgui._makeObject(mtrx1)
        'M', [[4, 5, 6, 7], [8, 9, 10, 11]]
        '''


if __name__ == '__main__':

    # Sample data.  example input strings that might be useful for representing
    # polynomials, matrices, etc.
    poly1 = "P: {1:10, 3:30}"             # A polynomial
    mtrx1 = "M: [[4,5,6,7],[8,9,10,11]]"  # A matrix

    cgui = CalcGUI(40, 5)  # Calculator display with a 40 x 5 stack

    def unittests():
        '''Nothing for now.'''

    from doctest import testmod
    testmod(verbose=True)
